/*
 * Copyright (c) 2009 Piotr Piastucki
 *
 * This file is part of Patchca CAPTCHA library.
 *
 * Patchca is free software: you can redistribute it and/or modify it under the
 * terms of the GNU Lesser General Public License as published by the Free
 * Software Foundation, either version 3 of the License, or (at your option) any
 * later version.
 *
 * Patchca is distributed in the hope that it will be useful, but WITHOUT ANY
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
 * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
 * details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with Patchca. If not, see <http://www.gnu.org/licenses/>.
 */
package org.patchca.service;

import java.awt.image.BufferedImage;

import org.patchca.background.BackgroundFactory;
import org.patchca.color.ColorFactory;
import org.patchca.filter.FilterFactory;
import org.patchca.font.FontFactory;
import org.patchca.text.renderer.TextRenderer;
import org.patchca.word.WordBean;
import org.patchca.word.WordFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public abstract class AbstractCaptchaService implements CaptchaService {
	protected final static Logger	logger	= LoggerFactory.getLogger(AbstractCaptchaService.class);

	protected FontFactory			fontFactory;
	protected WordFactory			wordFactory;
	protected ColorFactory			colorFactory;
	protected BackgroundFactory		backgroundFactory;
	protected TextRenderer			textRenderer;
	protected FilterFactory			filterFactory;
	protected int					width;
	protected int					height;

	public void setFontFactory(FontFactory fontFactory) {
		this.fontFactory = fontFactory;
	}

	public void setWordFactory(WordFactory wordFactory) {
		this.wordFactory = wordFactory;
	}

	public void setColorFactory(ColorFactory colorFactory) {
		this.colorFactory = colorFactory;
	}

	public void setBackgroundFactory(BackgroundFactory backgroundFactory) {
		this.backgroundFactory = backgroundFactory;
	}

	public void setTextRenderer(TextRenderer textRenderer) {
		this.textRenderer = textRenderer;
	}

	public void setFilterFactory(FilterFactory filterFactory) {
		this.filterFactory = filterFactory;
	}

	public FontFactory getFontFactory() {
		return this.fontFactory;
	}

	public WordFactory getWordFactory() {
		return this.wordFactory;
	}

	public ColorFactory getColorFactory() {
		return this.colorFactory;
	}

	public BackgroundFactory getBackgroundFactory() {
		return this.backgroundFactory;
	}

	public TextRenderer getTextRenderer() {
		return this.textRenderer;
	}

	public FilterFactory getFilterFactory() {
		return this.filterFactory;
	}

	public int getWidth() {
		return this.width;
	}

	public int getHeight() {
		return this.height;
	}

	public void setWidth(int width) {
		this.width = width;
	}

	public void setHeight(int height) {
		this.height = height;
	}

	@Override
	public Captcha getCaptcha() {
		long time1 = System.currentTimeMillis();
		BufferedImage bufImage = new BufferedImage(this.width, this.height, BufferedImage.TYPE_INT_ARGB);

		long time2 = System.currentTimeMillis();
		this.backgroundFactory.fillBackground(bufImage);

		long time3 = System.currentTimeMillis();
		WordBean wordBean = this.wordFactory.getNextWord();

		long time4 = System.currentTimeMillis();
		this.fontFactory.setWord(wordBean.getWord());
		this.textRenderer.draw(wordBean.getWord(), bufImage, this.fontFactory, this.colorFactory);

		long time5 = System.currentTimeMillis();
		bufImage = this.filterFactory.applyFilters(bufImage);

		long time6 = System.currentTimeMillis();

		Captcha captcha = new Captcha(wordBean.getWord(), wordBean.getAnswer(), bufImage, wordBean.getTips());

		if (logger.isDebugEnabled()) {
			logger.debug("allTime={},fillBackgroundTime={},genWordTime={},drawTime={},filteTime={}", time6 - time1, time3 - time2, time4 - time3,
					time5 - time4, time6 - time5);
		}
		return captcha;
	}

}
